home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / dos / printf.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-18  |  6.2 KB  |  299 lines

  1. /*
  2.  * Oh, it's a waste of space, but oh-so-yummy for debugging.  It's just
  3.  * initialization code anyway, so it doesn't take up space when we're
  4.  * actually running.  This version of printf() does not include 64-bit
  5.  * support.  "Live with it."
  6.  *
  7.  * Most of this code was shamelessly snarfed from the Linux kernel, then
  8.  * modified.  It's therefore GPL.
  9.  *
  10.  * printf() isn't actually needed to build syslinux.com, but during
  11.  * debugging it's handy.
  12.  */
  13.  
  14. #include <stdarg.h>
  15. #include <stdio.h>
  16. #include "mystuff.h"
  17.  
  18. static int strnlen(const char *s, int maxlen)
  19. {
  20.   const char *es = s;
  21.   while ( *es && maxlen ) {
  22.     es++; maxlen--;
  23.   }
  24.  
  25.   return (es-s);
  26. }
  27.  
  28. #define ZEROPAD    1        /* pad with zero */
  29. #define SIGN    2        /* unsigned/signed long */
  30. #define PLUS    4        /* show plus */
  31. #define SPACE    8        /* space if plus */
  32. #define LEFT    16        /* left justified */
  33. #define SPECIAL    32        /* 0x */
  34. #define LARGE    64        /* use 'ABCDEF' instead of 'abcdef' */
  35.  
  36. #define do_div(n,base) ({ \
  37. int __res; \
  38. __res = ((unsigned long) n) % (unsigned) base; \
  39. n = ((unsigned long) n) / (unsigned) base; \
  40. __res; })
  41.  
  42. static char * number(char * str, long num, int base, int size, int precision
  43.     ,int type)
  44. {
  45.   char c,sign,tmp[66];
  46.   const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
  47.   int i;
  48.   
  49.   if (type & LARGE)
  50.     digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  51.   if (type & LEFT)
  52.     type &= ~ZEROPAD;
  53.   if (base < 2 || base > 36)
  54.     return 0;
  55.   c = (type & ZEROPAD) ? '0' : ' ';
  56.   sign = 0;
  57.   if (type & SIGN) {
  58.     if (num < 0) {
  59.       sign = '-';
  60.       num = -num;
  61.       size--;
  62.     } else if (type & PLUS) {
  63.       sign = '+';
  64.       size--;
  65.     } else if (type & SPACE) {
  66.       sign = ' ';
  67.       size--;
  68.     }
  69.   }
  70.   if (type & SPECIAL) {
  71.     if (base == 16)
  72.       size -= 2;
  73.     else if (base == 8)
  74.       size--;
  75.   }
  76.   i = 0;
  77.   if (num == 0)
  78.     tmp[i++]='0';
  79.   else while (num != 0)
  80.     tmp[i++] = digits[do_div(num,base)];
  81.   if (i > precision)
  82.     precision = i;
  83.   size -= precision;
  84.   if (!(type&(ZEROPAD+LEFT)))
  85.     while(size-->0)
  86.       *str++ = ' ';
  87.   if (sign)
  88.     *str++ = sign;
  89.   if (type & SPECIAL) {
  90.     if (base==8)
  91.       *str++ = '0';
  92.     else if (base==16) {
  93.       *str++ = '0';
  94.       *str++ = digits[33];
  95.     }
  96.   }
  97.   if (!(type & LEFT))
  98.     while (size-- > 0)
  99.       *str++ = c;
  100.   while (i < precision--)
  101.     *str++ = '0';
  102.   while (i-- > 0)
  103.     *str++ = tmp[i];
  104.   while (size-- > 0)
  105.     *str++ = ' ';
  106.   return str;
  107. }
  108.  
  109. /* Forward decl. needed for IP address printing stuff... */
  110. int sprintf(char * buf, const char *fmt, ...);
  111.  
  112. int vsprintf(char *buf, const char *fmt, va_list args)
  113. {
  114.   int len;
  115.   unsigned long num;
  116.   int i, base;
  117.   char * str;
  118.   const char *s;
  119.   
  120.   int flags;        /* flags to number() */
  121.   
  122.   int field_width;    /* width of output field */
  123.   int precision;        /* min. # of digits for integers; max
  124.                    number of chars for from string */
  125.   int qualifier;        /* 'h', 'l', or 'L' for integer fields */
  126.   
  127.   for (str=buf ; *fmt ; ++fmt) {
  128.     if (*fmt != '%') {
  129.       *str++ = *fmt;
  130.       continue;
  131.     }
  132.     
  133.     /* process flags */
  134.     flags = 0;
  135.   repeat:
  136.     ++fmt;        /* this also skips first '%' */
  137.     switch (*fmt) {
  138.     case '-': flags |= LEFT; goto repeat;
  139.     case '+': flags |= PLUS; goto repeat;
  140.     case ' ': flags |= SPACE; goto repeat;
  141.     case '#': flags |= SPECIAL; goto repeat;
  142.     case '0': flags |= ZEROPAD; goto repeat;
  143.     }
  144.     
  145.     /* get field width */
  146.     field_width = -1;
  147.     if (isdigit(*fmt))
  148.       field_width = skip_atou(&fmt);
  149.     else if (*fmt == '*') {
  150.       ++fmt;
  151.       /* it's the next argument */
  152.       field_width = va_arg(args, int);
  153.       if (field_width < 0) {
  154.     field_width = -field_width;
  155.     flags |= LEFT;
  156.       }
  157.     }
  158.     
  159.     /* get the precision */
  160.     precision = -1;
  161.     if (*fmt == '.') {
  162.       ++fmt;    
  163.       if (isdigit(*fmt))
  164.     precision = skip_atou(&fmt);
  165.       else if (*fmt == '*') {
  166.     ++fmt;
  167.     /* it's the next argument */
  168.     precision = va_arg(args, int);
  169.       }
  170.       if (precision < 0)
  171.     precision = 0;
  172.     }
  173.     
  174.     /* get the conversion qualifier */
  175.     qualifier = -1;
  176.     if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
  177.       qualifier = *fmt;
  178.       ++fmt;
  179.     }
  180.     
  181.     /* default base */
  182.     base = 10;
  183.     
  184.     switch (*fmt) {
  185.     case 'c':
  186.       if (!(flags & LEFT))
  187.     while (--field_width > 0)
  188.       *str++ = ' ';
  189.       *str++ = (unsigned char) va_arg(args, int);
  190.       while (--field_width > 0)
  191.     *str++ = ' ';
  192.       continue;
  193.       
  194.     case 's':
  195.       s = va_arg(args, char *);
  196.       len = strnlen(s, precision);
  197.       
  198.       if (!(flags & LEFT))
  199.     while (len < field_width--)
  200.       *str++ = ' ';
  201.       for (i = 0; i < len; ++i)
  202.     *str++ = *s++;
  203.       while (len < field_width--)
  204.     *str++ = ' ';
  205.       continue;
  206.       
  207.     case 'p':
  208.       if (field_width == -1) {
  209.     field_width = 2*sizeof(void *);
  210.     flags |= ZEROPAD;
  211.       }
  212.       str = number(str,
  213.            (unsigned long) va_arg(args, void *), 16,
  214.            field_width, precision, flags);
  215.       continue;
  216.       
  217.       
  218.     case 'n':
  219.       if (qualifier == 'l') {
  220.     long * ip = va_arg(args, long *);
  221.     *ip = (str - buf);
  222.       } else {
  223.     int * ip = va_arg(args, int *);
  224.     *ip = (str - buf);
  225.       }
  226.       continue;
  227.       
  228.     case '%':
  229.       *str++ = '%';
  230.       continue;
  231.       
  232.       /* integer number formats - set up the flags and "break" */
  233.     case 'o':
  234.       base = 8;
  235.       break;
  236.       
  237.     case 'X':
  238.       flags |= LARGE;
  239.     case 'x':
  240.       base = 16;
  241.       break;
  242.       
  243.     case 'd':
  244.     case 'i':
  245.       flags |= SIGN;
  246.     case 'u':
  247.       break;
  248.       
  249.     default:
  250.       *str++ = '%';
  251.       if (*fmt)
  252.     *str++ = *fmt;
  253.       else
  254.     --fmt;
  255.       continue;
  256.     }
  257.     if (qualifier == 'l')
  258.       num = va_arg(args, unsigned long);
  259.     else if (qualifier == 'h') {
  260.       num = (unsigned short) va_arg(args, int);
  261.       if (flags & SIGN)
  262.     num = (short) num;
  263.     } else if (flags & SIGN)
  264.       num = va_arg(args, int);
  265.     else
  266.       num = va_arg(args, unsigned int);
  267.     str = number(str, num, base, field_width, precision, flags);
  268.   }
  269.   *str = '\0';
  270.   return str-buf;
  271. }
  272.  
  273. int sprintf(char * buf, const char *fmt, ...)
  274. {
  275.   va_list args;
  276.   int i;
  277.   
  278.   va_start(args, fmt);
  279.   i=vsprintf(buf,fmt,args);
  280.   va_end(args);
  281.   return i;
  282. }
  283.  
  284. int printf(const char *fmt, ...)
  285. {
  286.   char printf_buf[1024];
  287.   va_list args;
  288.   int printed;
  289.  
  290.   va_start(args, fmt);
  291.   printed = vsprintf(printf_buf, fmt, args);
  292.   va_end(args);
  293.  
  294.   puts(printf_buf);
  295.  
  296.   return printed;
  297. }
  298.  
  299.